using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Eve.API
{
    /// <summary>
    /// Represents detailed information about a character.
    /// </summary>
    /// <remarks>
    /// <para>The <b>CharacterSheet</b> class is returned by the <see cref="Eve.API.EveAPI.GetCharacterSheet">GetCharacterSheet</see> method in the <b>EveAPI</b> class, and provides detailed information about one character.</para>
    /// <para>This information is similar to what is displayed in the Character Sheet window in-game.</para>
    /// </remarks>
    [Serializable]
    public class CharacterSheet
    {
        /// <summary>
        /// Represents a character attribute or skill augmentation.
        /// </summary>
        [Serializable]
        public class Implant
        {
            private Attribute attribute;
            private string attributeName;
            private string name;
            private int value;

            /// <summary>
            /// Gets the attribute that this implant modifies.
            /// </summary>
            /// <value>
            /// A <b>0</b> indicates that the implant modifies a skill, otherwise an <see cref="Eve.API.Attribute">Attribute</see> member.
            /// </value>
            public Attribute Attribute
            {
                get { return attribute; }
            }
            /// <summary>
            /// Gets the name of the skill or attribute that this implant modifies.
            /// </summary>
            /// <value>The skill or attribute that is modified by this implant.</value>
            public string AttributeName
            {
                get { return attributeName; }
            }
            /// <summary>
            /// Gets the name of the implant.
            /// </summary>
            /// <value>
            /// The display name of the implant.
            /// </value>
            public string Name
            {
                get { return name; }
            }
            /// <summary>
            /// Gets the bonus value for this implant.
            /// </summary>
            /// <value>
            /// The bonus that this implant imparts.
            /// </value>
            public int Value
            {
                get { return value; }
            }

            internal Implant(XmlElement aug)
            {
                attributeName = aug.Name.Replace("Bonus", "");
                attribute = EveAPI.GetAttribute(attributeName);
                name = aug["augmentatorName"].InnerText;
                value = int.Parse(aug["augmentatorValue"].InnerText);
            }
        }
        /// <summary>
        /// Represents a skill that the character has learned.
        /// </summary>
        [Serializable]
        public class Skill
        {
            private int typeId;
            private int level;
            private int skillPoints;

            /// <summary>
            /// Gets the Eve internal type identifier for this skill.
            /// </summary>
            /// <value>The Eve internal type identifier for this skill.</value>
            /// <remarks>
            /// This value can be used with the <b>Eve.Data</b> class library to retrieve detailed information about the skill
            /// from the Eve Data Dump.
            /// </remarks>
            public int TypeId
            {
                get { return typeId; }
            }
            /// <summary>
            /// Gets the current level to which this skill is trained.
            /// </summary>
            /// <value>
            /// The current level to which this skill is trained.  The maximum trained level for a skill is 5.
            /// </value>
            public int Level
            {
                get { return level; }
            }
            /// <summary>
            /// Gets the total skill points trained in this skill.
            /// </summary>
            /// <value>
            /// The total number of skill points that have been trained for this skill.
            /// </value>
            public int SkillPoints
            {
                get { return skillPoints; }
            }

            internal Skill(XmlElement skill)
            {
                typeId = int.Parse(skill.Attributes["typeID"].Value);
                level = int.Parse(skill.Attributes["level"].Value);
                skillPoints = int.Parse(skill.Attributes["skillpoints"].Value);
            }
        }

        private long characterId;
        private string name;
        private string race;
        private string bloodline;
        private string gender;
        private string corporationName;
        private long corporationId;
        private double balance;
        private List<Implant> attributeEnhancers = new List<Implant>();
        private Dictionary<Attribute, int> attributes = new Dictionary<Attribute, int>();
        private List<Skill> skills = new List<Skill>();

        /// <summary>
        /// Gets the Eve internal identifier for the character.
        /// </summary>
        /// <value>
        /// The Eve internal identifier for the character.
        /// </value>
        public long CharacterId
        {
            get { return characterId; }
        }
        /// <summary>
        /// Gets the character's name.
        /// </summary>
        /// <value>
        /// The character's name.
        /// </value>
        public string Name
        {
            get { return name; }
        }
        /// <summary>
        /// Gets the character's race.
        /// </summary>
        /// <value>
        /// The character's race.
        /// </value>
        public string Race
        {
            get { return race; }
        }
        /// <summary>
        /// Gets the character's bloodline.
        /// </summary>
        /// <value>
        /// The character's bloodline.
        /// </value>
        public string Bloodline
        {
            get { return bloodline; }
        }
        /// <summary>
        /// Gets the character's gender
        /// </summary>
        /// <value>The character's gender</value>
        public string Gender
        {
            get { return gender; }
        }
        /// <summary>
        /// Gets the name of the corporation of which the character is a member.
        /// </summary>
        /// <value>The name of the corporation of which the character is a member.</value>
        public string CorporationName
        {
            get { return corporationName; }
        }
        /// <summary>
        /// Gets the Eve internal identifier of the corporation of which the character is a member.
        /// </summary>
        /// <value>
        /// The Eve internal identifier of the corporation of which the character is a member.
        /// </value>
        public long CorporationId
        {
            get { return corporationId; }
        }
        /// <summary>
        /// Gets the current balance in the character's personal wallet.
        /// </summary>
        /// <value>
        /// The current balance in the character's personal wallet.
        /// </value>
        public double WalletBalance
        {
            get { return balance; }
        }
        /// <summary>
        /// Gets a list of all implants currently being used by the character.
        /// </summary>
        /// <value>
        /// A list of all implants currently being used by the character.
        /// </value>
        public List<Implant> Implants
        {
            get { return attributeEnhancers; }
        }
        /// <summary>
        /// Gets the character's primary attribute values.
        /// </summary>
        /// <value>
        /// The character's primary attribute values.
        /// </value>
        public Dictionary<Attribute, int> Attributes
        {
            get { return attributes; }
        }
        /// <summary>
        /// Gets a list of all skills known by the character.
        /// </summary>
        /// <value>
        /// A list of all skills known by the character.
        /// </value>
        public List<Skill> Skills
        {
            get { return skills; }
        }

        internal CharacterSheet(XmlElement cs)
        {
            characterId = long.Parse(cs["characterID"].InnerText);
            name = cs["name"].InnerText;
            race = cs["race"].InnerText;
            bloodline = cs["bloodLine"].InnerText;
            gender = cs["gender"].InnerText;
            corporationName = cs["corporationName"].InnerText;
            corporationId = long.Parse(cs["corporationID"].InnerText);
            balance = double.Parse(cs["balance"].InnerText);
            foreach (XmlElement implant in cs["attributeEnhancers"].ChildNodes)
                attributeEnhancers.Add(new Implant(implant));
            foreach (XmlElement attribute in cs["attributes"].ChildNodes)
                attributes[EveAPI.GetAttribute(attribute.Name)] = int.Parse(attribute.InnerText);
            foreach (XmlElement rowset in cs.GetElementsByTagName("rowset"))
            {
                if (rowset.Attributes["name"].Value == "skills")
                {
                    foreach (XmlElement row in rowset.ChildNodes)
                        skills.Add(new CharacterSheet.Skill(row));
                }
            }
        }
    }
}
